using System;
using System.Collections.Generic;
using System.Text;

using DbOperation = SqlBlocks.ItemOperation<SqlBlocks.DatabaseOperationType>;

namespace SqlBlocks.Drivers
{
	public delegate void MockDatabaseEvent(string message);
	/// <summary>
	/// This is a mock database driver, and simply sends messages stating what it's doing to a subscriber
	/// </summary>
	public class MockDatabase : IDatabaseDriver
	{
		public event MockDatabaseEvent MockEvent;
		public void Commit(Changeset db, double version)
		{
			List<DbOperation> operations = db.GetPendingOperations();

			foreach (DbOperation operation in operations)
			{
				switch (operation.Type)
				{
					case DatabaseOperationType.RawSql:
						FireEvent("Running SQL:\r\n\t " + operation.GetData<string>());
						break;
					default:
						this.FireEvent("Not sure what we're doing");
						break;
				}
			}
		}

        public double CheckVersion(string connectionString)
        {
            return CheckVersion(connectionString, null);
        }
		public double CheckVersion(string connectionString, string group)
		{
			//Doesn't do much!
			return 0;
		}

        public string DumpSchema(string connectionString)
        {
            return "Hello Schema!";
        }

        public void LoadSchema(string connectionString, string schema)
        {
            FireEvent(string.Format("Loading schema: {0}", schema));
        }

        //void ProcessAddOrAlterTableOp(Changeset db, Table t)
        //{
        //    if (t.Mode == Mode.Create)
        //    {
        //        FireEvent("Adding a table: " + t.Name);
        //    }
        //    else
        //    {
        //        FireEvent("Altering a table: " + t.Name);
        //    }

        //    FireEvent("\t-----------------");
        //    FireEvent("\tColumn Operations");
        //    FireEvent("\t-----------------");
        //    OperationCollection<TableOperationType> columns = t.GetPendingOperations(
        //        TableOperationType.AddOrAlterColumn
        //        );
        //    foreach (TblOperation operation in columns)
        //    {
        //        ProcessAddOrAlterColumnOp(db, operation.GetData<Column>());
        //    }

        //    foreach (TblOperation operation in t.GetPendingOperations(TableOperationType.DropColumn))
        //    {
        //        FireEvent("\tDropping: " + operation.GetData<string>());
        //    }

        //    OperationCollection<TableOperationType> indexes = t.GetPendingOperations(TableOperationType.AddIndex);

        //    if(indexes.Count > 0)
        //    {
        //        FireEvent("\t-----------------");
        //        FireEvent("\tIndex Operations");
        //        FireEvent("\t-----------------");
        //    }

        //    foreach (TblOperation operation in indexes)
        //    {
        //        FireEvent("\tAdding index: " + operation.GetData<Index>());
        //    }
        //}

        //void ProcessAddOrAlterColumnOp(Changeset db, Column c)
        //{
        //    if (c.Mode == Mode.Create)
        //    {
        //        FireEvent(string.Format("\tAdding {0} {1}", c.Name, GetColumnDescription(c)));
        //    }
        //    else
        //    {
        //        FireEvent(string.Format("\tAltering {0} {1}", c.Name, GetColumnDescription(c)));
        //        //FireEvent("Altering a table: " + t.Name);
        //    }
        //}

        //string GetColumnDescription(Column c)
        //{
        //    SettingsCollection settings = c.GetSettings();
        //    string desc = "(" + settings["type"].ToString() + ")";

        //    foreach (string key in settings.Keys)
        //    {
        //        if ("type".Equals(key, StringComparison.CurrentCultureIgnoreCase))
        //        {
        //            continue;
        //        }
        //        desc += string.Format("\r\n\t\t{0}=\"{1}\"", key, settings[key]);
        //    }
        //    return desc;
        //}

		void FireEvent(string message)
		{
			if (this.MockEvent != null)
			{
				this.MockEvent(message);
			}
		}
	}
}